package com.chuangjiangx.member.stored.ddd.domain.model;

import com.chuangjiangx.dddbase.Repository;
import com.chuangjiangx.dddbase.domain.shared.Timestamp;
import com.chuangjiangx.domain.shared.model.PayTerminal;
import com.chuangjiangx.member.stored.dao.mapper.InMbrOrderRefundMapper;
import com.chuangjiangx.member.stored.dao.model.InMbrOrderRefund;
import com.chuangjiangx.member.basic.ddd.domain.model.MemberId;
import com.chuangjiangx.member.basic.ddd.domain.model.MerchantId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Optional;

/**
 * @author cj-ch
 * @date 2018/4/12 下午12:02
 */
@Component
public class MbrOrderRefundRepository implements Repository<MbrOrderRefund,MbrOrderRefundId> {

    @Autowired
    private InMbrOrderRefundMapper inMbrOrderRefundMapper;

    @Override
    public MbrOrderRefund fromId(MbrOrderRefundId mbrOrderRefundId) {
        InMbrOrderRefund in = inMbrOrderRefundMapper.selectByPrimaryKey(mbrOrderRefundId.getId());
        return in == null ? null : wrap(in);
    }

    @Override
    public void update(MbrOrderRefund mbrOrderRefund) {
        InMbrOrderRefund in = unbox(mbrOrderRefund);
        in.setUpdateTime(new Date());
        inMbrOrderRefundMapper.updateByPrimaryKeySelective(in);

    }

    @Override
    public void save(MbrOrderRefund mbrOrderRefund) {
        InMbrOrderRefund in = unbox(mbrOrderRefund);
        in.setCreateTime(new Date());
        inMbrOrderRefundMapper.insertSelective(in);
        mbrOrderRefund.setId(new MbrOrderRefundId(in.getId()));
    }

    private MbrOrderRefund wrap(InMbrOrderRefund in){
        MbrOrderRefund refund = new MbrOrderRefund(
            new MbrOrderId(in.getMbrOrderId()),
                in.getMbrRefundNumber(),
                new MerchantId(in.getMerchantId()),
                in.getMerchantUserId(),
                new MemberId(in.getMemberId()),
                in.getStoreId(),
                in.getStoreUserId(),
                MbrOrderRefundStatus.of(in.getStatus()),
                in.getRefundAmount(),
                in.getRefundTime(),
                null == in.getTerminal() ? null : PayTerminal.getPayTerminal(in.getTerminal())
        );
        refund.setId(new MbrOrderRefundId(in.getId()));
        refund.setTimestamp(new Timestamp(in.getCreateTime(),in.getUpdateTime()));
        return refund;
    }

    private InMbrOrderRefund unbox(MbrOrderRefund refund){
        Optional<MbrOrderRefund> optional = Optional.of(refund);
        InMbrOrderRefund in = new InMbrOrderRefund();
        in.setId(optional.map(MbrOrderRefund::getId).map(MbrOrderRefundId::getId).orElse(null));
        in.setMbrOrderId(refund.getMbrOrderId().getId());
        in.setMbrRefundNumber(refund.getMbrRefundNumber());
        in.setMemberId(refund.getMemberId().getId());
        in.setMerchantId(refund.getMerchantId().getId());
        in.setMerchantUserId(refund.getMerchantUserId());
        in.setRefundAmount(refund.getRefundAmount());
        in.setRefundTime(refund.getRefundTime());
        in.setStatus(refund.getStatus().value);
        in.setStoreId(refund.getStoreId());
        in.setStoreUserId(refund.getStoreUserId());
        in.setTerminal(null == refund.getTerminal() ? null : refund.getTerminal().code);
        Optional<Timestamp> timestamp = optional.map(MbrOrderRefund::getTimestamp);
        in.setCreateTime(timestamp.map(Timestamp::getCreateTime).orElse(null));
        in.setUpdateTime(timestamp.map(Timestamp::getUpdateTime).orElse(null));
        return in;
    }
}
